using System;
using System.IO;
using FM_Mono;
using UnityEngine;

namespace FibMatrix.IO
{
    public class PackageManager
    {
        private static IBaseStorageImpl _impl = new DefaultStorageImpl(streamingAssetsPath);

        static string s_StreamingAssetsPath;

        // 微信小游戏代码分包名
        /// 微信自己的文件系统，https://developers.weixin.qq.com/minigame/dev/guide/base-ability/file-system.html
        /// 分包是只读的，文件的访问方式是从项目根目录开始写文件路径，不支持相对路径的写法。我们可以暂时用预定义的wasmcode包
        [IgnoreGen] public const string WXCodeSubPackageName = "wasmcode";

        /// <summary>
        /// 编辑器中修改路径，使开发更方便
        /// </summary>
        public static string streamingAssetsPath
        {
            get
            {
                if (string.IsNullOrEmpty(s_StreamingAssetsPath))
                {
                    if (Application.isEditor)
                    {
                        // 编辑器里用构建目录
                        var root = Path.GetDirectoryName(Application.dataPath);
                        s_StreamingAssetsPath = Path.Combine(root, "Library/ProjectBuildCache/Package");
                    }
                    else
                    {
#if UNITY_WEBGL
                        s_StreamingAssetsPath = $"/{WXCodeSubPackageName}";
#else
                        s_StreamingAssetsPath = Application.streamingAssetsPath;
#endif
                    }
                }

                return s_StreamingAssetsPath;
            }
        }


        public static void Initialize(IBaseStorageImpl impl)
        {
            _impl = impl;
        }

        public static IBaseStorageImpl storageImpl => _impl;

        // 等价于streamingAssetsPath
        // public static string root
        // {
        //     get { return _impl.root; }
        // }

        public static bool Exists(string path, bool isFile = true)
        {
            return _impl.Exists(path, isFile);
        }

        [IgnoreGen]
        public static byte[] ReadAllBytes(string path)
        {
            return _impl.ReadAllBytes(path);
        }

        [IgnoreGen]
        public static string ReadAllText(string path)
        {
            return _impl.ReadAllText(path);
        }

        [IgnoreGen]
        public static byte[] ReadAllBytesIfExist(string path)
        {
            return _impl.Exists(path) ? _impl.ReadAllBytes(path) : null;
        }

        public static void ListDirectory(string path, bool recursive, StatMode mode, Action<string> visitFunc)
        {
            _impl.ListDirectory(path, recursive, mode, visitFunc);
        }

        public static Stream OpenRead(string path)
        {
            return _impl.OpenRead(path);
        }

        public static long GetFileSize(string path)
        {
            return _impl.GetFileSize(path);
        }
    }
}